﻿
namespace EntityProvider.Web
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using AbstraX.ServerInterfaces;
    using EntityProvider.Web.Entities;
    using System.Diagnostics;
    using MvvmTreeView;
    using AbstraX.Contracts;
    using AbstraX.TypeMappings;

    //  EntitiesRoot
    //    Solution
    //      Project
    //        Model
    //          Namespace
    //            Entity_Container
    //              Entity_Set
    //                EntityType
    //                  NavigationProperty
    //                    EntityType 

    [EnableClientAccess()]
    public class EntityProviderService : DomainService, IAbstraXProviderService
    {
        public IDomainHostApplication DomainServiceHostApplication { get; set; }

        [Invoke]
        public string GetRootID()
        {
            return new EntitiesRoot(this).ID;
        }

        public string GetDescription()
        {
            return null;
        }

        public EntitiesRoot GetRoots()
        {
            return new EntitiesRoot(this);
        }

        [Query]
        public IQueryable<Solution> GetSolutions()
        {
            Debug.WriteLine("Loading solutions");

            var hierarchy = new EntityProviderHierarchy<Solution>(this);
            var results = hierarchy.AsQueryable();

            return results;
        }

        [Query]
        public IQueryable<Project> GetProjects()
        {
            Debug.WriteLine("Loading projects");

            var hierarchy = new EntityProviderHierarchy<Project>(this);
            var results = hierarchy.AsQueryable();

            return results;
        }

        [Query]
        public IQueryable<Model> GetModels()
        {
            Debug.WriteLine("Loading models");

            var hierarchy = new EntityProviderHierarchy<Model>(this);
            var results = hierarchy.AsQueryable();

            return results;
        }

        [Query]
        public IQueryable<Entity_Container> GetEntityContainers()
        {
            Debug.WriteLine("Loading containers");

            var hierarchy = new EntityProviderHierarchy<Entity_Container>(this);
            var results = hierarchy.AsQueryable();

            return results;
        }

        [Query]
        public IQueryable<Entity_Set> GetEntitySets()
        {
            Debug.WriteLine("Loading entity sets");

            var hierarchy = new EntityProviderHierarchy<Entity_Set>(this);
            var results = hierarchy.AsQueryable();

            return results;
        }

        [Query]
        public IQueryable<EntityType> GetEntities()
        {
            Debug.WriteLine("Loading entities");

            var hierarchy = new EntityProviderHierarchy<EntityType>(this);
            var results = hierarchy.AsQueryable();

            return results;
        }

        [Query]
        public IQueryable<EntityProperty> GetEntityProperties()
        {
            Debug.WriteLine("Loading entity properties");

            var hierarchy = new EntityProviderHierarchy<EntityProperty>(this);
            var results = hierarchy.AsQueryable();

            return results;
        }

        [Query]
        public IQueryable<NavigationProperty> GetNavigationProperties()
        {
            Debug.WriteLine("Loading navigation properties");

            var hierarchy = new EntityProviderHierarchy<NavigationProperty>(this);
            var results = hierarchy.AsQueryable();

            return results;
        }

        [Query]
        public IQueryable<Solution> GetSolutionsForEntitiesRoot(string parentID)
        {
            Debug.WriteLine("Loading solutions for '" + parentID + "'");

            var hierarchy = new EntityProviderHierarchy<Solution>(this);
            var results = hierarchy.AsQueryable().Where(a => a.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<Project> GetProjectsForSolution(string parentID)
        {
            Debug.WriteLine("Loading projects for '" + parentID + "'");

            var hierarchy = new EntityProviderHierarchy<Project>(this);
            var results = hierarchy.AsQueryable().Where(a => a.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<Model> GetModelsForProject(string parentID)
        {
            Debug.WriteLine("Loading models for '" + parentID + "'");

            var hierarchy = new EntityProviderHierarchy<Model>(this);
            var results = hierarchy.AsQueryable().Where(a => a.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<Entity_Container> GetEntityContainersForModel(string parentID)
        {
            Debug.WriteLine("Loading containers for '" + parentID + "'");

            var hierarchy = new EntityProviderHierarchy<Entity_Container>(this);
            var results = hierarchy.AsQueryable().Where(a => a.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<Entity_Set> GetEntitySetsForEntity_Container(string parentID)
        {
            Debug.WriteLine("Loading entity sets for '" + parentID + "'");

            var hierarchy = new EntityProviderHierarchy<Entity_Set>(this);
            var results = hierarchy.AsQueryable().Where(a => a.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<EntityType> GetEntitiesForEntity_Set(string parentID)
        {
            Debug.WriteLine("Loading entities for '" + parentID + "'");

            var hierarchy = new EntityProviderHierarchy<EntityType>(this);
            var results = hierarchy.AsQueryable().Where(a => a.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<EntityProperty> GetEntityPropertiesForEntityType(string parentID)
        {
            Debug.WriteLine("Loading entity properties for '" + parentID + "'");

            var hierarchy = new EntityProviderHierarchy<EntityProperty>(this, parentID);
            var results = hierarchy.AsQueryable().Where(t => t.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<NavigationProperty> GetNavigationPropertiesForEntityType(string parentID)
        {
            Debug.WriteLine("Loading navigation properties for '" + parentID + "'");

            var hierarchy = new EntityProviderHierarchy<NavigationProperty>(this, parentID);
            var results = hierarchy.AsQueryable().Where(t => t.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<EntityType> GetEntitiesForNavigationProperty(string parentID)
        {
            Debug.WriteLine("Loading navigation properties for '" + parentID + "'");

            var hierarchy = new EntityProviderHierarchy<EntityType>(this, parentID);
            var results = hierarchy.AsQueryable().Where(t => t.ParentID == parentID);

            return results;
        }

        [Invoke]
        public byte[] GetImageForFolder(string folderKey)
        {
            Debug.WriteLine("Loading images for '" + folderKey + "'");

            var stream = this.GetType().Assembly.GetManifestResourceStream(folderKey);
            var bytes = new byte[stream.Length];

            stream.Read(bytes, 0, (int)stream.Length);

            return bytes;
        }

        [Invoke]
        public byte[] GetImageForItemType(string itemTypeName)
        {
            Debug.WriteLine("Loading images for '" + itemTypeName + "'");

            var attribute = (NodeImageAttribute)System.Type.GetType(itemTypeName).GetCustomAttributes(true).FirstOrDefault(a => a is NodeImageAttribute);

            var stream = this.GetType().Assembly.GetManifestResourceStream(attribute.ImagePath);
            var bytes = new byte[stream.Length];

            stream.Read(bytes, 0, (int)stream.Length);

            return bytes;
        }

        [Invoke]
        public byte[] GetImageForUrl(string url)
        {
            Debug.WriteLine("Loading images for '" + url + "'");

            var stream = this.GetType().Assembly.GetManifestResourceStream(url);
            var bytes = new byte[stream.Length];

            stream.Read(bytes, 0, (int)stream.Length);

            return bytes;
        }

        public IBase GenerateByID(string id)
        {
            return AbstraXExtensions.GenerateByID(this, id);
        }

        public ContainerType GetAllowableContainerTypes(string id)
        {
            throw new NotImplementedException();
        }

        public ConstructType GetAllowableConstructTypes(string id)
        {
            throw new NotImplementedException();
        }

        public SortedList<float, IPipelineStep> InitialPipelineSteps
        {
            get
            {
                return null;
            }
        }
    }
}


